import axios, { type AxiosRequestConfig, type Method } from "axios";
import logger from "./logger";
import NProgress from "@/plugins/nprogress";
import { showErrMessage } from "@/plugins/elementPlus/message";
import { getStorage } from "./storage";
import { AUTH_TOKEN_KEY } from "@/config/constant";

const BASE_URL = import.meta.env.VITE_APP_API_URL;

export interface CustomConfig {
    isAuth: boolean,//是否登录鉴权
    isSign: boolean,//是否签名
    isHandleError: boolean//统一处理业务异常
}

export interface IResponse<T> {
    code: number,
    data: T,
    msg: string,
    timestamp: number
}

logger.setNamespace("system").info("BASE_URL：", import.meta.env.VITE_APP_API_URL)

const instance = axios.create({
    baseURL: BASE_URL,
    timeout: 2500
})

//设置请求拦截器
instance.interceptors.request.use((config) => {
    return config
})

//响应拦截器
instance.interceptors.response.use(response => {
    return response
});

export const requestGet = <T = any>(url: string, data = {}, customConfig = {} as CustomConfig) => request(url, "GET", data, customConfig) as Promise<IResponse<T>>

export const requestPost = <T = any>(url: string, data = {}, customConfig = {} as CustomConfig) => request(url, "POST", data, customConfig) as Promise<IResponse<T>>

export const request = <T = any>(url: string, method: Method, data = {}, customConfig = {} as CustomConfig) => {
    //自定义配置
    let defaultCustomConfig: CustomConfig = {
        isAuth: true,
        isHandleError: true,
        isSign: false
    }
    const mergeCustomConfig = { ...defaultCustomConfig, ...customConfig }
    const config: AxiosRequestConfig = {
        url,
        method,
        data,
        headers: {}
    };
    if (config.headers && mergeCustomConfig.isAuth) {
        config.headers.Authorization = getStorage(AUTH_TOKEN_KEY)
    }
    NProgress.start()
    return new Promise((resolve, reject) => {
        let apiResponse: IResponse<T>
        //发起请求
        instance.request(config)
            //axios 请求成功
            .then(httpResponse => {
                apiResponse = httpResponse.data as IResponse<T>
                logger.info("【接口响应数据】：", apiResponse)
                //是否统一提示业务状态异常
                if (mergeCustomConfig.isHandleError) {
                    if (apiResponse.code != 0) {
                        showErrMessage(apiResponse.msg)
                        reject(apiResponse)
                        return
                    }
                }
                resolve(apiResponse)
            })
            //axios 请求错误
            .catch(err => {
                showErrMessage(err.message)
                reject(err)
            })
            .finally(() => {
                NProgress.done()
                logger.info("-----------------发起请求-----------------\r\n【请求API】:", BASE_URL + url, "\r\n【METHOD】:", method, "\r\n【DATA】:", data, "\r\n【MERGE_CONFIG】:", mergeCustomConfig, "\r\n【响应数据】：", apiResponse)
            })
    }) as Promise<IResponse<T>>
}